package com.ruoyi.project.test.gds.formal;

import cn.hutool.core.util.IdUtil;
import com.google.common.collect.Lists;
import com.ruoyi.project.test.gds.formal.mapper.GdsFileMapper;
import com.ruoyi.project.test.gds.formal.mapper.GdsGraphMapper;
import com.ruoyi.project.test.gds.formal.mapper.GdsStructureMapper;
import com.ruoyi.project.test.gds.formal.mapper.PointMapper;
import com.ruoyi.project.test.gds.formal.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
public class GdsParse {

    @Autowired
    public GdsFileMapper gdsFileMapper;
    @Autowired
    public GdsStructureMapper gdsStructureMapper;
    @Autowired
    public GdsGraphMapper gdsGraphMapper;
    @Autowired
    public PointMapper pointMapper;


    /**
     * 16进制转Ascii
     * @param hexStr
     * @return
     */
    public static String hexToAscii(String hexStr) {
        StringBuilder output = new StringBuilder("");
        for (int i = 0; i < hexStr.length(); i += 2) {
            String str = hexStr.substring(i, i + 2);
            output.append((char) Integer.parseInt(str, 16));
        }
        return output.toString();
    }

    /**
     * 将16进制转换为二进制
     *
     * @param hexString
     * @return
     */
    public static String hexString2binaryString(String hexString) {
        //16进制转10进制
        BigInteger sint = new BigInteger(hexString, 16);
        //10进制转2进制
        String result = sint.toString(2);
        return new StringBuilder(result).toString();
    }


    /**
     * 模块16进制内容解析
     * @param moldHex
     * @return
     */
    public GdsDTO hexConvertToTxt(String moldHex,GdsFile gdsFile,GdsStructure gdsStructure,GdsGraph gdsGraph) throws Exception {
        GdsDTO gdsDTO = new GdsDTO();
        int startIndex = 4;
        int endIndex = 8;
        int interval = 4;
        int coordinateInterval = 8;
        String result = "";
        String functionType = moldHex.substring(startIndex,endIndex);
        if (GdsParameter.HEADER.equals(functionType)
                || GdsParameter.GENETATIONS.equals(functionType)
                || GdsParameter.FORMAT.equals(functionType)
                || GdsParameter.ELFLAGS.equals(functionType)
                || GdsParameter.PLEX.equals(functionType)
                || GdsParameter.LAYER.equals(functionType)
                || GdsParameter.DATATYPE.equals(functionType)
                || GdsParameter.PATHTYPE.equals(functionType)
                || GdsParameter.WIDTH.equals(functionType)
                || GdsParameter.STRANS.equals(functionType)
                || GdsParameter.MAG.equals(functionType)
                || GdsParameter.ANGLE.equals(functionType)
                || GdsParameter.TEXTTYPE.equals(functionType)
                || GdsParameter.PERSENTATION.equals(functionType)
                || GdsParameter.NODETYPE.equals(functionType)
                || GdsParameter.BOXTYPE.equals(functionType)
        ){
            //int16,int32,int64
            int value = new BigInteger(moldHex.substring(endIndex), 16).intValue();
            if (GdsParameter.HEADER.equals(functionType)){
                gdsFile.setHeader(value);
            }
            if (GdsParameter.GENETATIONS.equals(functionType)){
                gdsFile.setGenetations(value);
            }
            if (GdsParameter.FORMAT.equals(functionType)){
                gdsFile.setFormat(value);
            }
            if (GdsParameter.ELFLAGS.equals(functionType)){
                gdsGraph.setElflags(value);
            }
            if (GdsParameter.PLEX.equals(functionType)){
                gdsGraph.setPlex(value);
            }
            if (GdsParameter.LAYER.equals(functionType)){
                gdsGraph.setLayer(value);
            }
            if (GdsParameter.DATATYPE.equals(functionType)){
                gdsGraph.setDatatype(value);
            }
            if (GdsParameter.PATHTYPE.equals(functionType)){
                gdsGraph.setPathtype(value);
            }
            if (GdsParameter.WIDTH.equals(functionType)){
                gdsGraph.setWidth(value);
            }
            if (GdsParameter.STRANS.equals(functionType)){
                gdsGraph.setStrans(value);
            }
            if (GdsParameter.MAG.equals(functionType)){
                gdsGraph.setMag(value);
            }
            if (GdsParameter.ANGLE.equals(functionType)){
                gdsGraph.setAngle(value);
            }
            if (GdsParameter.TEXTTYPE.equals(functionType)){
                gdsGraph.setTexttype(value);
            }
            if (GdsParameter.PERSENTATION.equals(functionType)){
                gdsGraph.setPersentation(value);
            }
            if (GdsParameter.NODETYPE.equals(functionType)){
                gdsGraph.setNodetype(value);
            }
            if (GdsParameter.BOXTYPE.equals(functionType)){
                gdsGraph.setBoxtype(value);
            }
            if (GdsParameter.STRANS.equals(functionType)){
                result= "插入模块结构的变换模式:"+String.valueOf(value);
            }else {
                result= String.valueOf(value);
            }

        }else if (GdsParameter.LIBNAME.equals(functionType)
                    || GdsParameter.REFLIBS.equals(functionType)
                    || GdsParameter.FONTS.equals(functionType)
                    || GdsParameter.ATTRTABLE.equals(functionType)
                    || GdsParameter.MASK.equals(functionType)
                    || GdsParameter.STRNAME.equals(functionType)
                    || GdsParameter.SNAME.equals(functionType)
                    || GdsParameter.ASCII.equals(functionType)
        ){
            //ASCII,char
            if (GdsParameter.SNAME.equals(functionType)){
                result="插入的是名称为"+hexToAscii(moldHex.substring(endIndex))+"的模块结构";
                gdsGraph.setSname(hexToAscii(moldHex.substring(endIndex)));
            }else {
                result=hexToAscii(moldHex.substring(endIndex));
                if (GdsParameter.LIBNAME.equals(functionType)){
                    gdsFile.setLibname(result);
                }
                if (GdsParameter.REFLIBS.equals(functionType)){
                    gdsFile.setReflibs(result);
                }
                if (GdsParameter.FONTS.equals(functionType)){
                    gdsFile.setFonts(result);
                }
                if (GdsParameter.ATTRTABLE.equals(functionType)){
                    gdsFile.setAttrtable(result);
                }
                if (GdsParameter.MASK.equals(functionType)){
                    gdsFile.setMask(result);
                }
                if (GdsParameter.STRNAME.equals(functionType)){
                    gdsStructure.setStrname(result);
                    //名称结束直接添加structure
                    gdsStructure.setId(IdUtil.getSnowflake().nextIdStr());
                    gdsStructure.setFileId(gdsFile.getId());
                    gdsStructureMapper.insertGdsStructure(gdsStructure);
                }
                if (GdsParameter.ASCII.equals(functionType)){
                    gdsGraph.setAscii(result);
                }
            }
        }else if (GdsParameter.CLOROW.equals(functionType)){
            //2个int16
            int row = new BigInteger(moldHex.substring(endIndex,endIndex+interval), 16).intValue();
            int col = new BigInteger(moldHex.substring(endIndex+interval), 16).intValue();
            gdsGraph.setRow(row);
            gdsGraph.setColumn(col);
            result="行="+row+",列="+col;
        }else if (GdsParameter.UNITS.equals(functionType)){
            //2个float64
            Double f1 = Double.longBitsToDouble(new BigInteger(moldHex.substring(endIndex,endIndex+16), 16).longValueExact());
//            System.out.println("转换后的单位二进制1："+hexString2binaryString(moldHex.substring(endIndex,endIndex+16)));
//            BigInteger b = new BigInteger(hexString2binaryString(moldHex.substring(endIndex,endIndex+16)), 2);
            Double f2 = Double.longBitsToDouble(new BigInteger(moldHex.substring(endIndex+16), 16).longValueExact());
//            System.out.println("转换后的单位二进制2："+hexString2binaryString(moldHex.substring(endIndex+16)));

            result = "默认导出单位（microns）：userunits=0.001"+",dbunits=0.001"+"\n"+"解析到单位（microns）：userunits="+String.valueOf(f1)+",dbunits="+String.valueOf(f2);
//            result = "userunits="+"0.001"+",dbunits="+"0.001";
            gdsFile.setUserUnit(1d);
            gdsFile.setDbUnit(1d);
            //单位结束新增file
            gdsFile.setId(IdUtil.getSnowflake().nextIdStr());
            gdsFileMapper.insertGdsFile(gdsFile);
        }else if (GdsParameter.XY.equals(functionType)){
            StringBuilder coordinate = new StringBuilder();
            List<Point> gdsPoints = Lists.newArrayList();

            while (endIndex<moldHex.length()){
                Point point = new Point();
                int x = new BigInteger(moldHex.substring(endIndex,endIndex+coordinateInterval), 16).intValue();
                point.x = x;
                int y = new BigInteger(moldHex.substring(endIndex+coordinateInterval,endIndex+coordinateInterval*2), 16).intValue();
                point.y = y;
                coordinate.append("(").append(x).append(",")
                        .append(y).append(")");
                endIndex+=coordinateInterval*2;
                point.setId(IdUtil.getSnowflake().nextIdStr());
                point.setGraphId(gdsGraph.getId());
                gdsPoints.add(point);
            }
            pointMapper.batchInsert(gdsPoints);
            result=coordinate.toString();
        }else if (GdsParameter.BGNLIB.equals(functionType)
                || GdsParameter.BGNSTR.equals(functionType)
        ){

            //12个int16
            int[] date = new int[12];
            for (int i = 0; i < date.length; i++) {
                int temp = new BigInteger(moldHex.substring(endIndex,endIndex+interval), 16).intValue();
                date[i]=temp;
                endIndex+=interval;
            }

            String t1=(date[0]+1900)+"年"+date[1]+"月"+date[2]+"日"+date[3]+"时"+date[4]+"分"+date[5]+"秒";
            String t2=(date[6]+1900)+"年"+date[7]+"月"+date[8]+"日"+date[9]+"时"+date[10]+"分"+date[11]+"秒";
            SimpleDateFormat format= new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
            Date temp1=format.parse(t1);
            Date temp2=format.parse(t2);
            if (GdsParameter.BGNLIB.equals(functionType)){
                result="最近修改时间为"+(date[0]+1900)+"年"+date[1]+"月"+date[2]+"日"+date[3]+"时"+date[4]+"分"+date[5]+
                        "秒-最近的存取时间为"+(date[6]+1900)+"年"+date[7]+"月"+date[8]+"日"+date[9]+"时"+date[10]+"分"+date[11]+"秒";
                gdsFile.setModifyTime(temp1);
                gdsFile.setReadTime(temp2);
            }else {
                result="模块结构创建时间为"+(date[0]+1900)+"年"+date[1]+"月"+date[2]+"日"+date[3]+"时"+date[4]+"分"+date[5]+
                        "秒-最后一次修改时间为"+(date[6]+1900)+"年"+date[7]+"月"+date[8]+"日"+date[9]+"时"+date[10]+"分"+date[11]+"秒";
                gdsStructure.setCreatTime(temp1);
                gdsStructure.setUpdateTime(temp2);
            }
        }else {
            if (GdsParameter.BOUNDARY.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.BOUNDARY));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.PATH.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.PATH));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.SREF.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.SREF));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.AREF.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.AREF));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.TEXT.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.TEXT));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.NODE.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.NODE));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.BOX.equals(functionType)){
                gdsGraph.setHeader(GdsParameter.gdsParameterMap.get(GdsParameter.BOX));
                if (gdsGraph.getId() == null){
                    gdsGraph.setId(IdUtil.getSnowflake().nextIdStr());
                }
            }
            if (GdsParameter.ENDNET.equals(functionType)){
                //图素结束存入graph
                gdsGraph.setStructureId(gdsStructure.getId());
                gdsGraphMapper.insertGdsGraph(gdsGraph);

            }
            //模块结构头，结束符返回空，不用解析
            result="";
        }
        gdsDTO.setResult(result);
        gdsDTO.setGdsFile(gdsFile);
        gdsDTO.setGdsStructure(gdsStructure);
        gdsDTO.setGdsGraph(gdsGraph);
        return gdsDTO;
    }

}
